home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARMCLUB / EUREKA / EUREKA29 / Programs / PhotoFiler / !PhotoFilr / WSWI-Help < prev   
Text File  |  1996-01-13  |  15KB  |  283 lines

  1. WimpSWIVe       0.05 (30 Oct 1995)
  2. ==================================
  3.  
  4.  
  5.  NewerLook needs to trap Wimp_ SWIs in order to provide its new error
  6. windows. The only official way to trap SWIs is to trap the SWI hardware
  7. vector, but even this is not recommended. It takes much code to implement
  8. properly in *all* circumstances (about 30K of source code in Desktop Hacker),
  9. and can slow the machine down, quite considerably when there are multiple
  10. claimants.
  11.  
  12.  It is, however, possible to trap Wimp_ SWIs by providing another module
  13. with the same SWI chunk and names. This method is much quicker and easier,
  14. but it is - as I’ll happily admit - rather dodgy. One of the problems is
  15. that only one module can do this at a time. So if NewerLook had a module
  16. that used this method, it wouldn’t work properly when another program tried
  17. to do the same thing. (And you know some program will.)
  18.  
  19.  Thus, I have separated the trapping code from the action code (which resides
  20. in another module), and released this module separately. It can manage SWI
  21. claims and releases dynamically, a bit like vectors. Actually, quite a lot
  22. like vectors. You can use it in your own programs if you like. Here’s how.
  23.  
  24.  Because WimpSWIVe uses the Wimp’s SWI chunk, it cannot provide its own
  25. SWIs. Instead, it communicates using a Wimp SWI, namely Wimp_RegisterFilter.
  26. Here is the WimpSWIVe specification for Wimp_RegisterFilter.
  27.  
  28.  
  29.             |                                             Wimp_RegisterFilter
  30.             |                                                    (SWI &400F5)
  31.             |
  32.             | Used by the Filter Manager to register or deregister a filter
  33.             | OR used to register SWI claims and releases with WimpSWIVe
  34.             |
  35.   On entry: | R0 = reason code:
  36.             |         &49575357 (“WSWI”) for WimpSWIVe operation (see below)
  37.             |         anything else for filter operation (see RISC OS 3
  38.             |         Programmers’ Reference Manual, page 3-224)
  39.             | R1 = SWI word:
  40.             |         bits 0-5 : offset in SWI chunk of SWI to claim/release
  41.             |         bit  6   : ignore bits 0-5 and claim all Wimp_ SWIs
  42.             |         bits 7-29: undefined, leave unset
  43.             |         bit  30  : high priority if set, else low priority
  44.             |         bit  31  : claim if set, else release
  45.             | R2 = value to be passed in R12 on entry to code
  46.             | R3 = address of SWI pre-trapping code, or 0 if none needed
  47.             | R4 = address of SWI post-trapping code, or 0 if none needed
  48.             |
  49.    On exit: | Registers preserved
  50.             |
  51. Interrupts: | Interrupts may be enabled
  52.             | Fast interrupts may be enabled
  53.             |
  54.  Processor: | Processor is in SVC mode
  55.             |
  56. Reentrancy: | SWI is not re-entrant
  57.             |
  58.        Use: | In WimpSWIVe usage, this SWI is used to claim or release SWIs.
  59.             | The pre-trapping code specified is called before the SWI is
  60.             | called, and the post-trapping code afterwards.
  61.             |
  62.             | High-priority pre-code is called before low priority pre-code.
  63.             | (And high-priority post-code is called after low priority
  64.             | post-code.) This is important because one piece of pre-code
  65.             | could intercept a SWI call before another bit got a look in.
  66.             | You should use high-priority code for monitoring and register-
  67.             | altering code. If your pre-code is at all likely to intercept
  68.             | a SWI, you must use low-priority code. In effect, low-priority
  69.             | code is ‘closer’ to the real SWI.
  70.             |
  71.             | Pre-trapping code conditions:
  72.             |
  73.             | On entry: R0-R8 = registers passed to SWI
  74.             |           R9    = offset into chunk of SWI called
  75.             |           R12   = value specified when RegisterFilter called
  76.             |           R13   = full, descending stack
  77.             |           R14   = return address
  78.             |  On exit: R0-R8 = may be altered to change effect of SWI
  79.             |           R9    = preserved, or -1 to intercept SWI
  80.             |
  81.             | Pre-trapping code is entered in SVC mode, with interrupts
  82.             | disabled. If R9=-1 on exit, the SWI is not called. Instead,
  83.             | any outstanding post-code is called, and the caller is returned
  84.             | to with the supplied R0-R8 and PSR flags. An error may be
  85.             | signified by pointing R0 to an error block and setting the V
  86.             | flag on return as normal, when intercepting. (See footnote 1.)
  87.             |
  88.             | If more than one client has claimed a SWI, it is the earliest
  89.             | claimant’s pre-trapping code that is called last - new
  90.             | claimants take priority (though high-priority always beats low-
  91.             | priority, of course). If interception occurs, any post-trapping
  92.             | code for claims where the pre-trapping code (if any) has
  93.             | already been executed are also executed. In effect, you are
  94.             | guaranteed that you will get a post-trap event if you have had
  95.             | a pre-trap. (See footnote 2.)
  96.             |
  97.             |
  98.             | Post-trapping code conditions:
  99.             |
  100.             | On entry: R0-R8 = registers passed back from SWI
  101.             |           R9    = offset into chunk of SWI called
  102.             |           R12   = value specified when RegisterFilter called
  103.             |           R13   = full, descending stack
  104.             |           R14   = return address
  105.             |  On exit: R0-R8 = may be altered to change perceived results
  106.             |           PSR flags may be altered to change perceived results
  107.             |           (for example to flag an error).
  108.             |
  109.             | Post-trapping code is entered in SVC mode, with interrupts
  110.             | disabled.
  111.             |
  112.             | If more than one client has claimed a SWI, it is the earliest
  113.             | claimant’s post-trapping code that is called first, subject
  114.             | to priority. (See footnote 2.)
  115.             |
  116.             | Remember that your post-trapping code may well be entered in an
  117.             | error condition. So check whether the V flag is set on entry,
  118.             | and return if it is (if you return with the S flag (MovS Pc,R14
  119.             | or LdmFd R13!,{...,Pc}^, the flags are unaffected). Never
  120.             | change the PSR flags by accident.
  121.             |
  122.             |
  123.             | Unlike OS_Claim, this SWI will not remove previous instances of
  124.             | claims with the same values. The release routine also only
  125.             | removes one instance of the values at a time.
  126.             |
  127.             | Claiming the Wimp_RegisterFilter SWI only traps the normal
  128.             | filter-based use of the SWI. Under no circumstances should you
  129.             | call Wimp_RegisterFilter with WimpSWIVe usage in your trapping
  130.             | code. If you really must claim or release a SWI when some other
  131.             | SWI is executed, use a CallBack to do it. (See the RISC OS 3
  132.             | Programmers’ Reference Manual, page 1-319.)
  133.             |
  134.             | Don’t post-trap Wimp_Poll(Idle) or Wimp_StartTask: it’s a bad
  135.             | idea. WimpSWIVe deals with it adequately, but there are all
  136.             | sorts of simply horrid implications. Trapping Wimp_Poll is
  137.             | easy anyway, using the old filter system.
  138.             |
  139.             | And finally, don’t use the ‘claim all SWIs’ flag unless you
  140.             | really want all the SWIs. Don’t use it for trapping a number
  141.             | of different SWIs, use many separate claims: the speed
  142.             | difference will be negligable, and you needn’t worry about
  143.             | Wimp_Poll. The ‘claim all SWIs’ flag is unlikely to be widely
  144.             | useful - a Wimp SWI logging program seems to be the only
  145.             | possible user.
  146.             |
  147.     Errors: | Bad value passed to WIMP in R0
  148.             |    if WimpSWIVe is not loaded, the attempt to use this SWI in
  149.             |    the WimpSWIVe manner will cause this error
  150.             | Bad WimpSWIVe release
  151.             |    releasing a SWI you had not claimed generates this error
  152.             | No room in RMA
  153.             |    is also possible but highly unlikely.
  154.             |
  155.  
  156.  
  157.  Footnote 1 - Re-entrancy issues:
  158.  
  159.  Re-entrancy is nae problem if you only use pre-trapping or only use post-
  160. trapping - you can either be re-entrant by using a stack to store stuff, or
  161. prevent re-entering using a threaded flag (and unless you call a SWI, you
  162. cannot be re-entered anyway). If you use both, but the post-code always does
  163. the same regardless of the pre-code, you’re all right too.
  164.  
  165.  But if you use both at once and the action of post depends on something
  166. that happened in pre (for example if you have pre to check the reason code
  167. is worth bothering with in the post-trap code), it is slightly more complex.
  168. It’s quite possible that calling a Wimp SWI may cause another Wimp SWI to be
  169. called, especially when you consider there can be many WimpSWIVe claimants.
  170. Consider:
  171.  
  172.      SWI Wimp_Thing called
  173.        WimpSWIVe claimant 1 pre-traps SWI
  174.          Claimant 1 store data for SWI 1 in workspace
  175.        WimpSWIVe claimant 2 pre-traps SWI
  176.          Claimant 2 executes Wimp_Gubbins
  177.            Wimp_Gubbins causes Wimp_Thing to be called
  178.              WimpSWIVe claimant 1 pre-traps SWI
  179.                Claimant 1 stores data for SWI 2 in workspace
  180.              WimpSWIVe claimant 2 pre-traps SWI
  181.                Claimant 2 is threaded, and so does nothing
  182.              WimpSWIVe executes real SWI Wimp_Thing
  183.              WimpSWIVe claimant 2 post-traps SWI
  184.                Claimant 2 is threaded, and so does nothing
  185.              WimpSWIVe claimant 1 post-traps SWI
  186.                Claimant 1 performs action on results, dependent on workspace
  187.                which holds data for SWI 2
  188.              WimpSWIVe returns
  189.        WimpSWIVe executes real Wimp_Thing SWI
  190.        WimpSWIVe claimant 2 post-traps SWI
  191.          Claimant 2 does whatever it needs to with results
  192.        WimpSWIVe claimant 1 post-traps SWI
  193.          Claimant 1 performs action on results, dependent on workspace
  194.          which holds data for SWI *2*
  195.        WimpSWIVe returns
  196.  
  197.  As you can see, there is a lot of scope here for things going wrong, and
  198. horrible clashes where one WimpSWIVe program may make another go wrong,
  199. potentially rather messily.
  200.  
  201.  There are two things you can do about it. Perhaps the best is to store a
  202. ‘count’ of post-traps to ignore. This count should be zero initially, and
  203. should be incremented first when your pre-trap code detects that post-
  204. trapping should do something effective. It should also be incremented every
  205. time the pre-trap code is entered with the count non-zero. The post trap code
  206. then checks the count on entry. If the count is zero, it returns doing
  207. nothing. If the count is one or greater, the count is decremented. If the
  208. count is one exactly one, the effect of the post-trap is activated. There’s
  209. an example of this in the EigenSysInfo source.
  210.  
  211.  This is fine normally, but it makes the trapping code only affect the first
  212. SWI to be affected (the "outermost" affected SWI). If you want to be truly
  213. re-entrant, you’d have to store values on the stack to indicate whether to
  214. post-trap on each call. And you couldn’t use the SVC stack, so you’d have to
  215. use a private stack. And you’d have to revert to the above behaviour if the
  216. stack was filled up. Therefore, I don’t reckon it’s worth bothering with,
  217. especially as allowing true re-entrancy opens the door to recursive problems
  218. (Wimp_Thing calls Wimp_Gubbins calls Wimp_Thing calls Wimp_Gubbins etc.) too.
  219.  
  220.  Sorry about the complexity of this footnote. Relax. You don’t need to
  221. bother about all this horrid stuff, usually. :-)
  222.  
  223.  
  224.  Footnote 2:
  225.  
  226.  Your post-trap code will only be called if the SWI does return. This might
  227. not happen if the SWI is one that doesn’t return (but I can’t think of any
  228. Wimp_ SWIs that don’t), or if a serious error happens. The latter should
  229. never happen in a perfect system, but bugs happen and the SWI being trapped
  230. might branch through zero or something. With the Wimp, though, a crash at
  231. this stage often means there is something very wrong with the whole desktop
  232. and everything is going to die anyway, so your module failing to post-trap
  233. is unlikely to annoy the user much. :-)
  234.  
  235. -----------------------------------------------------------------------------
  236.  
  237.  This module is supplied with some example programs:
  238.  
  239.  - 3DErrorWindow. This is a useful module that replaces the WIMP’s error
  240.    windows with its own Risc PCable 3D ones (it needs 3DErrorWindow$Path to
  241.    point to a directory containing Templates and Messages - you can find one
  242.    in Sources.ErrorWind) using pre-trapping (usually with interception). The
  243.    windows could do with the NewerLook ‘titlejoint’ sprite in the wimp pool,
  244.    along with the Risc PC error system sprites. Note that this is an OLD
  245.    VERSION of 3DErrorWindow, which you should not actually use - get
  246.    NewerLook for the fullest, newest version. This, however, is a better
  247.    example of how to use WimpSWIVe, as it is less complicated than the
  248.    latest version.
  249.  - EigenSysInfo. This is a pretty useless one that changes Wimp_ReadSysInfo
  250.    2 always to return 24 or 22, and return the latter if Log2YEig<2 (the
  251.    WIMP returns 22 if Log2YEig==Log2XEig, which is silly). It also goes
  252.    ‘beep’ if the Wimp returned a different value to it (try mode 22 and the
  253.    like). It’s not particularly great because most programs don’t take any
  254.    notice of ReadSysInfo (partly because of its aforementioned bobbinsness)
  255.    but it shows you how to pre-trap and post-trap SWIs at the same time (as
  256.    in footnote 1).
  257.  
  258.  The source for these programs, along with the full source to WimpSWIVe and
  259. some resources for 3DErrorWindow are to be found in the Sources directory.
  260. However, these programs require BAX to be loaded for them to compile. BAX is
  261. DoggySoft’s Basic Assembler Extension, which provides all ARM3, ARM6, FPA10
  262. and coprocessor instructions, along with many useful pseudo-instructions.
  263. You can get BAX from good PD libraries and Arcade, Digital Databank and
  264. Furzefield Hq BBSs. It’s essential for Basic assembler programmers!
  265.  
  266.  If you use this module in a program, be sure to RMEnsure version 0.04 or
  267. later - versions 0.01 and 0.02 are NewerLook quick releases with bugs in
  268. post-trapping, and version 0.03 does not feature high-priority SWI trapping,
  269. as well as sometimes entering pre-code with interrupts enabled.
  270.  
  271.  This module is freeware. Free free to distribute and use. To contact me -
  272. for praise, to suggest new bits to add, or (heaven forbid) to report a bug,
  273. please write to:
  274.  
  275.   Andrew Clover,
  276.    7 Blackhorse Crescent,
  277.     Amersham,
  278.      Bucks.,
  279.       HP6 6HP.
  280.  
  281.  Or phone me on 01494-431916, send a fax on 01494-675878, send some email to
  282. ajc@doggysft.demon.co.uk or even telex on 83675 Brit G.
  283.